#include <iostream>
#include <string>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <cerrno>
#include <iostream>
#include <cstdio>
using namespace std;
class TcpClient
{
  private:
    int _sockfd;
    int _sever_port;
    string _sever_ip;
  public:
    TcpClient(string ip , int port)
      :_sever_ip(ip),
      _sever_port(port),
      _sockfd(-1)
    {}
    ~TcpClient()
    {
      if(_sockfd >= 0)
      {
        close(_sockfd);
      }
    }
  public:
    void ClientInit()
    {
      _sockfd = socket(AF_INET , SOCK_STREAM , 0);
      if (_sockfd < 0)
      {
        cout << "ClientInit error" << endl;
        exit(1);
      }
    }

    void Request()
    {
      string msg;
      char buff[1024];

      while(true)
      {
        cout << "please enter#" ;
        fflush(nullptr);
        getline(cin , msg);
        write(_sockfd , msg.c_str() , msg.size());

        ssize_t size = read(_sockfd , buff , sizeof(buff) -1);
        if(size > 0)
        {
          buff[size] = 0; // '\0'
          cout << "sever echo: " << buff << endl ; 
        }
        else if (size == 0)
        {
          cout << "sever exit " << endl ;
          break;
        }
        else 
        {
          cout << "sever error" << endl;
          break;
        }
      }

      close(_sockfd);
    }


    void ClientStart()
    {
      struct sockaddr_in peer;
      memset(&peer , 0 , sizeof(peer));

      peer.sin_family = AF_INET;
      peer.sin_port = htons(_sever_port);
      peer.sin_addr.s_addr = inet_addr(_sever_ip.c_str());

      if (connect(_sockfd , (struct sockaddr*)&peer , sizeof(peer)) == 0)
      {
        cout << "connect success" << endl;
        Request();
      }
      else 
      {
        cout << "connect fail" << endl;
        exit(2);
      }
    }
};


int main(int argc , char* argv[])
{
  if (argc != 3)
  {
    cout << "usage error" << endl; 
    exit(3);
  }

  string ip = argv[1];
  int port = atoi(argv[2]);

  auto* clt = new TcpClient(ip , port);
  clt->ClientInit();
  clt->ClientStart();
  return 0;
}
